#include "SpotLightEffect.h"

SpotLightEffect::SpotLightEffect(const LPDIRECT3DDEVICE9 device, EffectManager *effMgr, TextureManager *texMgr) :Effect(device, effMgr, texMgr)
{
	xpos = ypos = 0;
}

SpotLightEffect::~SpotLightEffect(void)
{
}

void SpotLightEffect::renderSpotLight(Camera *camera, SpotLight *spotLight, ModelMesh *coneLight, LPDIRECT3DSURFACE9 prevSurf)
{
	device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

	device->SetRenderTarget(0, *texMgr->getSurface(L"lightMap"));

	effMgr->setupEffect(DEF_SPOT_LIGHT_FX);
	effMgr->getSetEffect()->SetTexture("colorMap" , texMgr->getTexture(L"colorMap"));
	effMgr->getSetEffect()->SetTexture("normalMap", texMgr->getTexture(L"normalMap"));
	effMgr->getSetEffect()->SetTexture("depthMap" , texMgr->getTexture(L"depthMap"));

	effMgr->getSetEffect()->SetMatrix("View", &camera->getViewMatrix());
	effMgr->getSetEffect()->SetMatrix("Projection", &camera->getProjMatrix());

	// Shadow
	effMgr->getSetEffect()->SetTexture("shadowMap", texMgr->getTexture(L"shadowMap"));
	effMgr->getSetEffect()->SetTexture("lightTexture", texMgr->getTexture(LIGHT_TEX));
	effMgr->getSetEffect()->SetMatrix("lightWorldViewProj", &(spotLight->getViewProjMatrix()));

	effMgr->getSetEffect()->SetMatrix("World", &spotLight->getWorldMatrix());
	effMgr->getSetEffect()->SetVector("lightDirection", &spotLight->getDirection4());
	effMgr->getSetEffect()->SetVector("lightPosition", &spotLight->getPosition4());
	effMgr->getSetEffect()->SetVector("Color", &spotLight->getColor());
	effMgr->getSetEffect()->SetFloat("lightRadius", spotLight->getRadius());
	effMgr->getSetEffect()->SetFloat("lightIntensity", spotLight->getIntensity());
	effMgr->getSetEffect()->SetFloat("lightDecayExponent", spotLight->getDecay());

	FLOAT hyp = 1.0f;
	FLOAT base = 0.5f;
	FLOAT adj = (hyp * hyp) - (base * base) ;
	FLOAT cosAngle = adj/hyp;

	effMgr->getSetEffect()->SetFloat("lightAngleCosine", cosAngle);
	effMgr->getSetEffect()->SetVector("cameraPosition", &camera->getPosition4());
	effMgr->getSetEffect()->SetMatrix("InvertViewProjection", &camera->getInvViewProjMatrix());
	effMgr->getSetEffect()->SetVector("halfPixel", &commonValues::halfPixel);

	D3DXVECTOR4 diff;
	diff.x = spotLight->getPosition3().x - camera->getPosition3().x;
	diff.y = spotLight->getPosition3().y - camera->getPosition3().y;
	diff.z = spotLight->getPosition3().z - camera->getPosition3().z;
	FLOAT cameraToCenter = sqrt(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z);

	if (cameraToCenter < spotLight->getRadius() * 2.0f)
	{
		device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
	}
	else
	{
		device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
	}

	UINT numPasses;
	device->BeginScene();
	effMgr->getSetEffect()->Begin(&numPasses, 0);
	effMgr->getSetEffect()->BeginPass(0);
	coneLight->getMesh()->DrawSubset(0);
	effMgr->getSetEffect()->EndPass();
	effMgr->getSetEffect()->End();
	device->EndScene();

	device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
	device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
	device->SetRenderTarget(0, prevSurf);
}